package it.uniroma2.exp.dtk;

import it.uniroma2.exp.AbstractExperiment;
import it.uniroma2.util.math.ArrayMath;
import it.uniroma2.util.vector.RandomVectorGenerator;

import java.util.ArrayList;

public class SpaceTester extends AbstractExperiment {
	
	private ArrayList<double[]> vectors;
	private double epsilon;
	private double[] epsilons = new double[0];
	private boolean unlimited = false;
	
	public void setEpsilons(double[] epsilons) {
		this.epsilons = epsilons;
		setCustomParameters(new int[] {epsilons.length});
	}
	
	public void setUnlimited(boolean unlimited) {
		this.unlimited = unlimited;
	}
	
	public void printCount() {
		out.println("Found (at least) "+vectors.size()+" vectors with dot product < "+epsilon);
	}

	@Override
	protected void runExperiment() throws Exception {
		RandomVectorGenerator rvg = new RandomVectorGenerator(vectorSize, randomOffset);
		epsilon = epsilons[currentCustomParameters[0]];
		if (vectors == null)
			vectors = new ArrayList<double[]>();
		else
			vectors.clear();
		int c = 0, i = 0;
		while (c < vectorSize || unlimited) {
			if (i++ % 1000 == 0)
				out.print(".");
			double[] newVector = rvg.generateRandomVector();
			boolean ok = true;
			for (double[] oldVector : vectors)
				if (ArrayMath.dot(oldVector, newVector) >= epsilon) {
					ok = false;
					break;
				}
			if (ok) {
				vectors.add(newVector);
				c = 0;
			}
			else
				c++;
		}
		out.println();
	}

	/**
	 * @param args t to keep searching for new vectors until execution is interrupted
	 */
	public static void main(String[] args) {
		final SpaceTester st = new SpaceTester();
		if (args.length > 0 && args[0].equalsIgnoreCase("t")) {
			st.setUnlimited(true);
			Runtime.getRuntime().addShutdownHook(new Thread() {
				@Override
				public void run() {
					st.printCount();
				}
			});
		}
		st.setVectorSize(4096);
		st.setEpsilons(new double[] {0.01, 0.05, 0.1});
		st.runAll();
	}

}
